home *** CD-ROM | disk | FTP | other *** search
/ Aminet 52 / Aminet 52 (2002)(GTI - Schatztruhe)[!][Dec 2002].iso / Aminet / game / think / AmiChess.lha / AmiChess / src / move.c < prev    next >
C/C++ Source or Header  |  2002-10-31  |  13KB  |  610 lines

  1. #include <clib/alib_protos.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <ctype.h>
  6. #include "common.h"
  7.  
  8. void MakeMove(short side,int *move)
  9. {
  10. BitBoard *a;
  11. short f,t,fpiece,tpiece; 
  12. short rookf,rookt,epsq,sq;
  13. short xside;
  14. GameRec *g;
  15. xside=1^side;
  16. f=FROMSQ(*move);
  17. t=TOSQ(*move);
  18. fpiece=cboard[f];
  19. tpiece=cboard[t];
  20. a=&board.b[side][fpiece];
  21. CLEARBIT(*a,f);
  22. SETBIT(*a,t);
  23. CLEARBIT(board.blockerr90,r90[f]);
  24. SETBIT(board.blockerr90,r90[t]);
  25. CLEARBIT(board.blockerr45,r45[f]);
  26. SETBIT(board.blockerr45,r45[t]);
  27. CLEARBIT(board.blockerr315,r315[f]);
  28. SETBIT(board.blockerr315,r315[t]);
  29. cboard[f]=empty;
  30. cboard[t]=fpiece;
  31. GameCnt++;
  32. g=&Game[GameCnt];
  33. g->epsq=board.ep; 
  34. g->bflag=board.flag;
  35. g->Game50=Game50;
  36. g->hashkey=HashKey;
  37. g->phashkey=PawnHashKey;
  38. g->mvboard=Mvboard[t];
  39. Mvboard[t]=Mvboard[f]+1; 
  40. Mvboard[f]=0;
  41. if(board.ep>-1) HashKey^=ephash[board.ep];
  42. HashKey^=hashcode[side][fpiece][f];
  43. HashKey^=hashcode[side][fpiece][t];
  44. if(fpiece==king) board.king[side]=t;
  45. if(fpiece==pawn)
  46.     {
  47.     PawnHashKey^=hashcode[side][pawn][f];
  48.     PawnHashKey^=hashcode[side][pawn][t];
  49.     }
  50. if(tpiece)
  51.     {
  52.     ExchCnt[side]++;
  53.     CLEARBIT(board.b[xside][tpiece],t);
  54.     *move|=(tpiece<<15);
  55.     HashKey^=hashcode[xside][tpiece][t];
  56.     if(tpiece==pawn) PawnHashKey^=hashcode[xside][pawn][t];
  57.     board.material[xside]-=Value[tpiece];
  58.     if(tpiece!=pawn) board.pmaterial[xside]-=Value[tpiece];
  59.     }
  60. if(*move&PROMOTION)
  61.     {
  62.     SETBIT(board.b[side][PROMOTEPIECE(*move)],t);
  63.     CLEARBIT(*a,t);
  64.     cboard[t]=PROMOTEPIECE(*move);
  65.     HashKey^=hashcode[side][pawn][t];
  66.     HashKey^=hashcode[side][cboard[t]][t];
  67.     PawnHashKey^=hashcode[side][pawn][t];
  68.     board.material[side]+=(Value[cboard[t]]-ValueP);
  69.     board.pmaterial[side]+=Value[cboard[t]];
  70.     }
  71. if(*move&ENPASSANT)
  72.     {
  73.     ExchCnt[side]++;
  74.     epsq=board.ep+(side==white?-8:8);
  75.     CLEARBIT(board.b[xside][pawn],epsq);
  76.     CLEARBIT(board.blockerr90,r90[epsq]);
  77.     CLEARBIT(board.blockerr45,r45[epsq]);
  78.     CLEARBIT(board.blockerr315,r315[epsq]);
  79.     cboard[epsq]=empty;
  80.     HashKey^=hashcode[xside][pawn][epsq];
  81.     PawnHashKey^=hashcode[xside][pawn][epsq];
  82.     board.material[xside]-=ValueP;
  83.     }
  84. if(*move&(CAPTURE|CASTLING)||fpiece==pawn) Game50=GameCnt;
  85. if(*move&CASTLING)
  86.     {
  87.     if(t&0x04)
  88.         {
  89.         rookf=t+1;
  90.         rookt=t-1;
  91.         }
  92.     else
  93.         {
  94.         rookf=t-2;
  95.         rookt=t+1;
  96.         }
  97.     a=&board.b[side][rook];
  98.     CLEARBIT(*a,rookf);
  99.     SETBIT(*a,rookt);
  100.     CLEARBIT(board.blockerr90,r90[rookf]);
  101.     SETBIT(board.blockerr90,r90[rookt]);
  102.     CLEARBIT(board.blockerr45,r45[rookf]);
  103.     SETBIT(board.blockerr45,r45[rookt]);
  104.     CLEARBIT(board.blockerr315,r315[rookf]);
  105.     SETBIT(board.blockerr315,r315[rookt]);
  106.     cboard[rookf]=empty;
  107.     cboard[rookt]=rook;
  108.     Mvboard[rookf]=0;
  109.     Mvboard[rookt]=1;
  110.     HashKey^=hashcode[side][rook][rookf];
  111.     HashKey^=hashcode[side][rook][rookt];
  112.     board.castled[side]=true;
  113.     }
  114. if(side==white)
  115.     {
  116.     if(fpiece==king&&board.flag&WCASTLE)
  117.         {
  118.         if(board.flag&WKINGCASTLE) HashKey^=WKCastlehash;
  119.         if(board.flag&WQUEENCASTLE) HashKey^=WQCastlehash;
  120.         board.flag&=~WCASTLE;
  121.         }
  122.     else if(fpiece==rook)
  123.         {
  124.         if(f==H1)
  125.             {
  126.             if(board.flag&WKINGCASTLE) HashKey^=WKCastlehash;
  127.             board.flag&=~WKINGCASTLE;
  128.             }
  129.         else if(f==A1) 
  130.             {
  131.             if(board.flag&WQUEENCASTLE) HashKey^=WQCastlehash;
  132.             board.flag&=~WQUEENCASTLE;
  133.             }
  134.         }
  135.     if(tpiece==rook)
  136.         {
  137.         if(t==H8) 
  138.             {
  139.             if(board.flag&BKINGCASTLE) HashKey^=BKCastlehash;
  140.             board.flag&=~BKINGCASTLE;
  141.             }
  142.         else if(t==A8) 
  143.             {
  144.             if(board.flag&BQUEENCASTLE) HashKey^=BQCastlehash;
  145.             board.flag&=~BQUEENCASTLE;
  146.             }
  147.         }
  148.     }
  149. else
  150.     {
  151.     if(fpiece==king&&board.flag&BCASTLE)
  152.         {
  153.         if(board.flag&BKINGCASTLE) HashKey^=BKCastlehash;
  154.         if(board.flag&BQUEENCASTLE) HashKey^=BQCastlehash;
  155.         board.flag&=~BCASTLE;
  156.         }
  157.     else if(fpiece==rook)
  158.         {
  159.         if(f==H8) 
  160.             {
  161.             if(board.flag&BKINGCASTLE) HashKey^=BKCastlehash;
  162.             board.flag&=~BKINGCASTLE;
  163.             }
  164.         else if(f==A8) 
  165.             {
  166.             if(board.flag&BQUEENCASTLE) HashKey^=BQCastlehash;
  167.             board.flag&=~BQUEENCASTLE;
  168.             }
  169.         }
  170.     if(tpiece==rook)
  171.         {
  172.         if(t==H1) 
  173.             {
  174.             if(board.flag&WKINGCASTLE) HashKey^=WKCastlehash;
  175.             board.flag&=~WKINGCASTLE;
  176.             }
  177.         else if(t==A1) 
  178.             {
  179.             if(board.flag&WQUEENCASTLE) HashKey^=WQCastlehash;
  180.             board.flag&=~WQUEENCASTLE;
  181.             }
  182.         }
  183.     }
  184. if(fpiece==pawn&&abs(f-t)==16)
  185.     {
  186.     sq=(f+t)/2;
  187.     board.ep=sq;
  188.     HashKey^=ephash[sq];
  189.     }
  190. else board.ep=-1;
  191. board.side=xside;
  192. HashKey^=Sidehash;
  193. UpdateFriends();
  194. g->move=*move;
  195. }
  196.  
  197. void UnmakeMove(short side,int *move)
  198. {
  199. BitBoard *a;
  200. short f,t,fpiece,cpiece;   
  201. short rookf,rookt,epsq;
  202. short xside;
  203. GameRec *g;
  204. side=1^side;
  205. xside=1^side;
  206. f=FROMSQ(*move);
  207. t=TOSQ(*move);
  208. fpiece=cboard[t];
  209. cpiece=CAPTUREPIECE(*move);
  210. a=&board.b[side][fpiece];
  211. CLEARBIT(*a,t);
  212. SETBIT(*a,f);   
  213. CLEARBIT(board.blockerr90,r90[t]); 
  214. SETBIT(board.blockerr90,r90[f]); 
  215. CLEARBIT(board.blockerr45,r45[t]); 
  216. SETBIT(board.blockerr45,r45[f]); 
  217. CLEARBIT(board.blockerr315,r315[t]); 
  218. SETBIT(board.blockerr315,r315[f]); 
  219. cboard[f]=cboard[t];
  220. cboard[t]=empty;
  221. g=&Game[GameCnt];
  222. Mvboard[f]=Mvboard[t]-1;
  223. Mvboard[t]=g->mvboard;
  224. if(fpiece==king)
  225. board.king[side]=f;
  226. if(*move&CAPTURE)
  227.     {
  228.     ExchCnt[side]--;
  229.     SETBIT(board.b[xside][cpiece],t);  
  230.     SETBIT(board.blockerr90,r90[t]);  
  231.     SETBIT(board.blockerr45,r45[t]);  
  232.     SETBIT(board.blockerr315,r315[t]);  
  233.     cboard[t]=cpiece; 
  234.     board.material[xside]+=Value[cpiece];  
  235.     if(cpiece!=pawn)
  236.     board.pmaterial[xside]+=Value[cpiece];  
  237.     }
  238. if(*move&PROMOTION)
  239.     {
  240.     CLEARBIT(*a,f);
  241.     SETBIT(board.b[side][pawn],f);  
  242.     cboard[f]=pawn;
  243.     board.material[side]+=(ValueP-Value[PROMOTEPIECE(*move)]); 
  244.     board.pmaterial[side]-=Value[PROMOTEPIECE(*move)];
  245.     }
  246. if(*move&ENPASSANT)
  247.     {
  248.     ExchCnt[side]--;
  249.     epsq =(side==white?g->epsq-8:g->epsq+8);
  250.     SETBIT(board.b[xside][pawn],epsq); 
  251.     SETBIT(board.blockerr90,r90[epsq]); 
  252.     SETBIT(board.blockerr45,r45[epsq]); 
  253.     SETBIT(board.blockerr315,r315[epsq]); 
  254.     cboard[epsq]=pawn;
  255.     board.material[xside]+=ValueP;  
  256.     }   
  257. if(*move&CASTLING)
  258.     {
  259.     if(t&0x04)
  260.         {
  261.         rookf=t+1;
  262.         rookt=t-1;
  263.         }
  264.     else
  265.         {
  266.         rookf=t-2;
  267.         rookt=t+1;
  268.         }
  269.     a=&board.b[side][rook];
  270.     CLEARBIT(*a,rookt);
  271.     SETBIT(*a,rookf); 
  272.     CLEARBIT(board.blockerr90,r90[rookt]);
  273.     SETBIT(board.blockerr90,r90[rookf]);
  274.     CLEARBIT(board.blockerr45,r45[rookt]);
  275.     SETBIT(board.blockerr45,r45[rookf]);
  276.     CLEARBIT(board.blockerr315,r315[rookt]);
  277.     SETBIT(board.blockerr315,r315[rookf]);
  278.     cboard[rookf]=rook;
  279.     cboard[rookt]=empty;
  280.     Mvboard[rookf]=0;
  281.     Mvboard[rookt]=0;    
  282.     board.castled[side]=false;
  283.     }
  284. UpdateFriends();
  285. board.side=side;
  286. board.ep=g->epsq;
  287. board.flag=g->bflag;  
  288. HashKey=g->hashkey;
  289. PawnHashKey=g->phashkey;
  290. Game50=g->Game50;
  291. GameCnt--;
  292. }
  293.  
  294. void SANMove(int move,short ply)
  295. {
  296. short piece,side,ambiguous;
  297. short f,t;
  298. BitBoard b;
  299. leaf *node1;
  300. char *s;
  301. side=board.side;
  302. s=SANmv;
  303. f=FROMSQ(move);
  304. t=TOSQ(move);
  305. if(move&CASTLING)
  306.     {
  307.     if(t==6||t==62) strcpy(s,"O-O");
  308.     else strcpy(s,"O-O-O");
  309.     return;
  310.     }
  311. piece=cboard[f];
  312. side=board.side;
  313. b=board.b[side][piece];
  314. ambiguous=false;
  315. node1=TreePtr[ply];
  316. if(nbits(b)>1)
  317.     {
  318.     for(node1=TreePtr[ply];node1<TreePtr[ply+1];node1++)
  319.         {
  320.         if(FROMSQ(node1->move)==f) continue;
  321.         if(TOSQ(node1->move)!=t) continue;
  322.         if(cboard[FROMSQ(node1->move)]!=piece) continue;
  323.         ambiguous=true;
  324.         break;
  325.         }
  326.     }
  327. if(piece==pawn)
  328.     {
  329.     if(cboard[t]||board.ep==t)
  330.         {
  331.         *s++=algbrfile[ROW(f)];
  332.         *s++='x';
  333.         }
  334.     strcpy(s,algbr[t]);
  335.     s+=2;
  336.     if(move&PROMOTION)
  337.         {
  338.         *s++='=';
  339.         *s++=notation[PROMOTEPIECE(move)];
  340.         }
  341.     }
  342. else
  343.     {
  344.     *s++=notation[piece];
  345.     if(ambiguous)
  346.         {
  347.         if(ROW(f)==ROW(FROMSQ(node1->move))) *s++=algbrrank[RANK(f)];
  348.         else *s++=algbrfile[ROW(f)];
  349.         }
  350.     if(cboard[t]) *s++='x'; 
  351.     strcpy(s,algbr[t]);
  352.     s+=2;
  353.     }
  354. MakeMove(side,&move);
  355. if(SqAtakd(board.king[1^side],side))
  356.     {
  357.     TreePtr[ply+2]=TreePtr[ply+1];
  358.     GenCheckEscapes(ply+1);
  359.     if(TreePtr[ply+1]==TreePtr[ply+2]) *s++='#';
  360.     else *s++='+';
  361.     GenCnt-=TreePtr[ply+2]-TreePtr[ply+1];
  362.     }
  363. UnmakeMove(1^side,&move); 
  364. *s=0;
  365. }
  366.  
  367. #define ASCIITOFILE(a) ((a)-'a')
  368. #define ASCIITORANK(a) ((a)-'1')
  369. #define ASCIITOSQ(a,b) (ASCIITOFILE(a))+(ASCIITORANK(b))*8
  370. #define ATOH(a)((a)>='a'&&(a)<='h')
  371. #define ITO8(a)((a)>='1'&&(a)<='8')
  372.  
  373. leaf *ValidateMove(char *s)
  374. {
  375. short f,t,side,rank,file,fileto;
  376. short piece,kount;
  377. char mvstr[64],*p;
  378. char text[100];
  379. BitBoard b;
  380. leaf *n1,*n2;
  381. TreePtr[2]=TreePtr[1];
  382. GenMoves(1);   
  383. FilterIllegalMoves(1);    
  384. side=board.side;
  385. p=mvstr;
  386. do
  387.     {
  388.     if(*s!='x'&&*s!='+'&&*s!='=') *p++=*s; 
  389.     }
  390. while(*s++);
  391. if(mvstr[strlen(mvstr)-1]=='+'||mvstr[strlen(mvstr)-1]=='#'||mvstr[strlen(mvstr)-1]=='=') mvstr[strlen(mvstr)-1]=0;
  392. if(strcmp(mvstr,"O-O")==0||strcmp(mvstr,"o-o")==0||strcmp(mvstr,"0-0")==0)
  393.     {
  394.     if(side==white)
  395.         {
  396.         f=4;
  397.         t=6;
  398.         }
  399.     else 
  400.         {
  401.         f=60;
  402.         t=62;
  403.         }
  404.     return IsInMoveList(1,f,t,' ');
  405.     }
  406. if(strcmp(mvstr,"O-O-O")==0||strcmp(mvstr,"o-o-o")==0||strcmp(mvstr,"0-0-0")==0)
  407.     {
  408.     if(side==white)
  409.         {
  410.         f=4;
  411.         t=2;
  412.         }
  413.     else
  414.         {
  415.         f=60;
  416.         t=58;
  417.         }
  418.     return IsInMoveList(1,f,t,' ');
  419.     }
  420. if(ATOH(mvstr[0])&&ITO8(mvstr[1])&&ATOH(mvstr[2])&&ITO8(mvstr[3]))
  421.     {
  422.     f=ASCIITOSQ(mvstr[0],mvstr[1]);
  423.     t=ASCIITOSQ(mvstr[2],mvstr[3]);
  424.     piece=(strlen(mvstr)==5?mvstr[4]:' ');
  425.     return IsInMoveList(1,f,t,piece);
  426.     }
  427. if(ATOH(mvstr[0]))
  428.     {
  429.     if(ITO8(mvstr[1]))
  430.         {
  431.         t=ASCIITOSQ(mvstr[0],mvstr[1]);
  432.         f=t+(side==white?-8:8);
  433.         if(f>0&&f<64)
  434.             {
  435.             if(BitPosArray[f]&board.b[side][pawn])
  436.                 {
  437.                 if(mvstr[2]) return IsInMoveList(1,f,t,mvstr[2]);
  438.                 else return IsInMoveList(1,f,t,' ');
  439.                 }
  440.             f=t+(side==white?-16:16);
  441.             if(f>0&&f<64)
  442.                 {
  443.                 if(BitPosArray[f]&board.b[side][pawn]) return IsInMoveList(1,f,t,' ');
  444.                 }
  445.             }
  446.         }
  447.     else if(ATOH(mvstr[1])&&ITO8(mvstr[2]))
  448.         {
  449.         t=ASCIITOSQ(mvstr[1],mvstr[2]);
  450.         rank=ASCIITORANK(mvstr[2])+(side==white?-1:1);
  451.         f=rank*8+ASCIITOFILE(mvstr[0]);
  452.         piece=(strlen(mvstr)==4?mvstr[3]:' ');
  453.         return IsInMoveList(1,f,t,piece);
  454.         }
  455.     else if(ATOH(mvstr[1]))
  456.         {
  457.         file=ASCIITOFILE(mvstr[0]);
  458.         fileto=ASCIITOFILE(mvstr[1]);
  459.         b=board.b[side][pawn]&FileBit[file];
  460.         if(side==white) b=b>>(fileto<file?7:9);
  461.         else b=b<<(fileto<file?9:7);
  462.         if(board.ep>-1) b=b&(board.friends[1^side]|BitPosArray[board.ep]);
  463.         else b=b&(board.friends[1^side]);
  464.         switch(nbits(b))
  465.             {
  466.             case 0:
  467.                 return 0;
  468.             case 1:
  469.                 t=leadz(b);
  470.                 f=t-(side==white?8:-8)+(file-fileto);
  471.                 piece=(strlen(mvstr)==3?mvstr[2]:' ');
  472.                 return IsInMoveList(1,f,t,piece);
  473.             default:
  474.                 sprintf(text,"Ambiguous move: %s %s",s,mvstr);
  475.                 DoMethod(mui_app,MUIM_Chess_ShowThinking,text);
  476. /*                DoMethod(mui_app,MUIM_Chess_ShowBoard); */
  477.                 return 0;
  478.             }
  479.         } 
  480.     }
  481. else if(strchr("NBRQK",mvstr[0]))
  482.     {
  483.     piece=empty;
  484.     if(mvstr[0]=='N') piece=knight;
  485.     else if(mvstr[0]=='B') piece=bishop;
  486.     else if(mvstr[0]=='R') piece=rook;
  487.     else if(mvstr[0]=='Q') piece=queen;
  488.     else if(mvstr[0]=='K') piece=king;
  489.     b=board.b[side][piece];
  490.     t=-1;
  491.     if(ITO8(mvstr[1]))
  492.         {
  493.         rank=ASCIITORANK(mvstr[1]);
  494.         b&=RankBit[rank];
  495.         t=ASCIITOSQ(mvstr[2],mvstr[3]);
  496.         }
  497.     else if(ATOH(mvstr[1])&&ATOH(mvstr[2]))
  498.         {
  499.         file=ASCIITOFILE(mvstr[1]);
  500.         b&=FileBit[file];
  501.         t=ASCIITOSQ(mvstr[2],mvstr[3]);
  502.         }
  503.     else if(ATOH(mvstr[1])&&ITO8(mvstr[2])) t=ASCIITOSQ(mvstr[1],mvstr[2]);
  504.     kount=0;
  505.     n1=0;
  506.     n2=0;
  507.     while(b)
  508.         {
  509.         f=leadz(b);
  510.         CLEARBIT(b,f);
  511.         if(n1=IsInMoveList(1,f,t,' '))
  512.             {
  513.             n2=n1;
  514.             kount++;
  515.             }
  516.         }
  517.     if(kount>1)
  518.         {
  519.         sprintf(text,"Ambiguous move: %s %s",s,mvstr);
  520.         DoMethod(mui_app,MUIM_Chess_ShowThinking,text);
  521. /*        DoMethod(mui_app,MUIM_Chess_ShowBoard); */
  522.         return 0;
  523.         }
  524.     if(kount==0) return 0;
  525.     return n2;
  526.     }
  527. return 0;
  528. }
  529.  
  530. leaf *IsInMoveList(short ply,short f,short t,char piece)
  531. {
  532. leaf *node;
  533. for(node=TreePtr[ply];node<TreePtr[ply+1];node++)
  534.     {
  535.     if((short)(node->move&0x0FFF)==MOVE(f,t)&&toupper(piece)==notation[PROMOTEPIECE(node->move)]) return node;
  536.     }
  537. return 0;
  538. }
  539.  
  540. short IsLegalMove(int move)
  541. {
  542. short f,t,piece,side;
  543. BitBoard blocker,enemy;
  544. f=FROMSQ(move); 
  545. t=TOSQ(move);
  546. if(cboard[f]==empty) return false;
  547. side=board.side;
  548. if(!(BitPosArray[f]&board.friends[side])) return false;
  549. if(BitPosArray[t]&board.friends[side]) return false;
  550. piece=cboard[f];
  551. if((move &(PROMOTION|ENPASSANT))&&piece!=pawn) return false;
  552. if((move&ENPASSANT)&&t!=board.ep) return false;
  553. if((move&CASTLING)&&piece!=king) return false; 
  554. blocker=board.blocker;
  555. if(piece==pawn)
  556.     {
  557.     if((move&ENPASSANT)&&board.ep>-1) enemy=board.friends[1^side]|BitPosArray[board.ep];
  558.     else enemy=board.friends[1^side];
  559.     if(side==white)
  560.         {
  561.         if(!(MoveArray[pawn][f]&BitPosArray[t]&enemy)&&!(t-f==8&&cboard[t]==empty)&&!(t-f==16&&RANK(f)==1&&!(FromToRay[f][t]&blocker))) return false;
  562.         }
  563.     else if(side==black)
  564.         {
  565.         if(!(MoveArray[bpawn][f]&BitPosArray[t]&enemy)&&!(t-f==-8&&cboard[t]==empty)&&!(t-f==-16&&RANK(f)==6&&!(FromToRay[f][t]&blocker))) return false;
  566.         }
  567.     }
  568. else if(piece==king)
  569.     {
  570.     if(side==white)
  571.         {
  572.         if(!(MoveArray[piece][f]&BitPosArray[t])&&!(f==E1&&t==G1&&board.flag&WKINGCASTLE&&!(FromToRay[E1][G1]&blocker)&&!SqAtakd(E1,black)&&!SqAtakd(F1,black))&&!(f==E1&&t==C1&&board.flag&WQUEENCASTLE&&
  573.         !(FromToRay[E1][B1]&blocker)&&!SqAtakd(E1,black)&&!SqAtakd(D1,black))) return false;
  574.         }
  575.     if(side==black)
  576.         {
  577.         if(!(MoveArray[piece][f]&BitPosArray[t])&&!(f==E8&&t==G8&&board.flag&BKINGCASTLE&&!(FromToRay[E8][G8]&blocker)&&!SqAtakd(E8,white)&&!SqAtakd(F8,white))&&!(f==E8&&t==C8&&board.flag&BQUEENCASTLE&&
  578.         !(FromToRay[E8][B8]&blocker)&&!SqAtakd(E8,white)&&!SqAtakd(D8,white))) return false;
  579.         }
  580.     }
  581. else 
  582.     {
  583.     if(!(MoveArray[piece][f]&BitPosArray[t])) return false;
  584.     }
  585. if(slider[piece])
  586.     {
  587.     if(FromToRay[f][t]&NotBitPosArray[t]&blocker) return false;
  588.     }
  589. return true;
  590. }
  591.  
  592. static char s[6];
  593. char *AlgbrMove(int move)
  594. {
  595. short f,t;
  596. f=FROMSQ(move);
  597. t=TOSQ(move);
  598. strcpy(s,algbr[f]);
  599. strcpy(s+2,algbr[t]);
  600. if(move&PROMOTION)
  601.     {
  602.     /* s[4]=lnotation[PROMOTEPIECE(move)]; */
  603.     s[4]=notation[PROMOTEPIECE(move)];
  604.     s[5]=0;
  605.     }
  606. else s[4]=0;
  607. return s;
  608. }
  609.  
  610.